﻿#include "MqttClient.h"

#include <QCoreApplication>
#include <QJsonObject>
#include <QJsonArray>
#include <QJsonDocument>
#include <QFile>
#include <QTimer>

MqttClient::MqttClient(QObject *parent)
    : QObject(parent)
{
    QString configPath = QCoreApplication::applicationDirPath() + "/config/config.json";
    loadConfig(configPath);

    initMQTT();

    // test
    testSend();
}

MqttClient::~MqttClient()
{

}

QString MqttClient::getServerIp() const
{
    return m_serverIp;
}

uint16_t MqttClient::getServerPort() const
{
    return m_serverPort;
}

QStringList MqttClient::getPublishTopics() const
{
    return m_publishTopics;
}

QStringList MqttClient::getSubTopics() const
{
    return m_subTopics;
}

void MqttClient::publishMessage(const QString &topic, const QByteArray &message)
{
    m_client->publish(QMQTT::Message(0, topic, message, 1));
}

void MqttClient::loadConfig(const QString &configPath)
{
    QJsonObject root;
    QFile file(configPath);
    if(file.open(QIODevice::ReadOnly))
    {
        root = QJsonDocument::fromJson(file.readAll()).object();
        file.close();
    }

    m_serverIp = root["ServerIp"].toString();
    m_serverPort = root["ServerPort"].toInt();

    // 发布主题
    QJsonArray publishByteArray = root["PublishTopic"].toArray();
    for(const auto& publishObject : publishByteArray)
    {
        m_publishTopics.append(publishObject.toString());
    }

    // 订阅主题
    QJsonArray subTopicByteArray = root["SubTopic"].toArray();
    for(const auto& subObject : subTopicByteArray)
    {
        m_subTopics.append(subObject.toString());
    }
}

void MqttClient::initMQTT()
{
    m_client = new QMQTT::Client(QHostAddress(m_serverIp), m_serverPort);

    // 设置连接信号
    connect(m_client, &QMQTT::Client::connected, this, &MqttClient::OnConnected);
    connect(m_client, &QMQTT::Client::disconnected, this, &MqttClient::OnDisconnected);
    connect(m_client, &QMQTT::Client::error, this, &MqttClient::OnError);
    connect(m_client, &QMQTT::Client::subscribed, this, &MqttClient::OnSubscribed);
    connect(m_client, &QMQTT::Client::unsubscribed, this, &MqttClient::OnUnsubscribed);
    connect(m_client, &QMQTT::Client::published, this, &MqttClient::OnPublished);
    connect(m_client, &QMQTT::Client::received, this, &MqttClient::OnReceived);
    connect(m_client, &QMQTT::Client::pingresp, this, &MqttClient::OnPingresp);

    m_client->setClientId("MQTTClient");
    m_client->setUsername("MQTTClient");

    m_client->setKeepAlive(60);
    m_client->setAutoReconnect(true);
    m_client->setCleanSession(true);
    m_client->connectToHost();
}

void MqttClient::OnConnected()
{

}

void MqttClient::OnDisconnected()
{

}

void MqttClient::OnError(const QMQTT::ClientError error)
{
    qDebug() << __FUNCTION__ << __LINE__ << QMQTT::ClientError(error);
}

void MqttClient::OnSubscribed(const QString &topic, const quint8 qos)
{

}

void MqttClient::OnUnsubscribed(const QString &topic)
{

}

void MqttClient::OnPublished(const QMQTT::Message &message, quint16 msgid)
{
    QString topic = message.topic();
}

void MqttClient::OnReceived(const QMQTT::Message &message)
{

}

void MqttClient::OnPingresp()
{

}

void MqttClient::testSend()
{
    publishMessage(m_publishTopics[0], m_publishTopics[0].toStdString().c_str());

    QTimer::singleShot(1000, this, &MqttClient::testSend);
}
